package com.freedom.start.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.lang.reflect.Method;

/**
 * @Author: zhenggang.liu
 * @Date: 2019/8/9 15:49
 */


public class CustomFilter extends FormAuthenticationFilter {

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        String username = super.getUsername(request);
        String password = super.getPassword(request);
        boolean remember = super.isRememberMe(request);
        // return super.createToken(request, response);
        return new UsernamePasswordToken(username, password, remember, null);
    }


    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        return super.executeLogin(request, response);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        boolean accessAllowed = super.isAccessAllowed(request, response, mappedValue);
        return accessAllowed;
        // return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        Object principal = getSubject(request, response).getPrincipal();
        return super.onAccessDenied(request, response);
    }

    @Override
    protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        super.issueSuccessRedirect(request, response);
        /*String successUrl = getSuccessUrl();
        boolean contextRelative = true;
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
        if (savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)) {
            if(!savedRequest.getRequestUrl().equals(request.getServletContext().getContextPath()+"/")){
                successUrl = savedRequest.getRequestUrl();
                contextRelative = false;
            }

        }

        if (successUrl == null) {
            throw new IllegalStateException("Success URL not available via saved request or via the " +
                    "successUrlFallback method parameter. One of these must be non-null for " +
                    "issueSuccessRedirect() to work.");
        }

        WebUtils.issueRedirect(request, response, successUrl, null, contextRelative);*/
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        return super.onLoginSuccess(token, subject, request, response);
        // return true;
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        String clazz = Thread.currentThread().getStackTrace()[1].getClassName();
        String method = Thread.currentThread().getStackTrace()[1].getMethodName();
        System.out.println("class name: " + clazz + ", Method Name: " + method);
        String name = e.getClass().getName(), message = e.getMessage();

        if (IncorrectCredentialsException.class.getName().equals(name)) {
            message = "密码错误";
        }
        request.setAttribute("message", message);
        return super.onLoginFailure(token, e, request, response);
        // return true;
        // return false;
    }


}
